﻿using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Windows;
using System.Windows.Input;
using System.Windows.Navigation;
using Lasalara.ViewModel;
using RestSharp;
using ServiceStack.Text;

namespace Lasalara.View
{
    public partial class LoginRegister
    {
        private readonly UserViewModel _userViewModel = new UserViewModel();
        // Constructor
        public LoginRegister()
        {
            InitializeComponent();
            // Initialize click handlers
            loginButton.Click += LoginButtonClick;
            forgotPasswordButton.Click += ForgotPasswordButtonClick;
            sendPasswordButton.Click += SendPasswordButtonClick;
            registerButton.Click += RegisterButtonClick;
        }

        /// <summary>
        /// Navigates to the books page
        /// </summary>
        protected override void OnNavigatedTo(NavigationEventArgs navigationEventArgs)
        {
            if (NavigationContext.QueryString.ContainsKey("loggedOut"))
            {
                NavigationContext.QueryString.Remove("loggedOut");
                NavigationService.RemoveBackEntry();
            }
            if (UserViewModel.IsUserLoggedIn())
            {
                // Supplies (fromLogin = "true") parameter to disable back button when user navigates from
                // login page to books page.
                NavigationService.Navigate(new Uri("/View/Books.xaml?fromLogin=true", UriKind.Relative));
            }
        }

        #region progressbar visibility

        /// <summary>
        /// Shows loading image and hides buttons if forgot password web request is in progress
        /// </summary>
        /// <param name="inProgress">Is a web request currently in progress?</param>
        private void IsForgotPasswordInProgress(bool inProgress)
        {
            if (inProgress)
            {
                sendPasswordButton.Visibility = Visibility.Collapsed;
                forgotProgressBar.Text = AppResources.ForgotPasswordLoading;
                forgotProgressBar.ShowProgress = true;
                forgotProgressBar.Visibility = Visibility.Visible;
            }
            else
            {
                forgotProgressBar.ShowProgress = false;
                forgotProgressBar.Visibility = Visibility.Collapsed;
                sendPasswordButton.Visibility = Visibility.Visible;
            }
        }

        /// <summary>
        /// Shows loading image and hides buttons if logging in web request is in progress
        /// </summary>
        /// <param name="logging">Is a web request currently in progress?</param>
        private void IsLoggingInProgress(bool logging)
        {
            if (logging)
            {
                loginButton.Visibility = Visibility.Collapsed;
                forgotPasswordButton.Visibility = Visibility.Collapsed;
                loginProgressBar.ShowProgress = true;
                loginProgressBar.Text = AppResources.LoggingInLoading;
                loginProgressBar.Visibility = Visibility.Visible;
            }
            else
            {
                loginProgressBar.ShowProgress = false;
                loginProgressBar.Visibility = Visibility.Collapsed;
                loginButton.Visibility = Visibility.Visible;
                forgotPasswordButton.Visibility = Visibility.Visible;
            }
        }

        /// <summary>
        /// Shows loading image and hides buttons if registering web request is in progress
        /// </summary>
        /// <param name="registering">Is a web request currently in progress?</param>
        private void IsRegisterInProgress(bool registering)
        {
            if (registering)
            {
                registerButton.Visibility = Visibility.Collapsed;
                registerProgressBar.Visibility = Visibility.Visible;
            }
            else
            {
                registerProgressBar.Visibility = Visibility.Collapsed;
                registerButton.Visibility = Visibility.Visible;
            }
        }

        #endregion

        #region validation

        /// <summary>
        /// Validates login fields
        /// </summary>
        private bool AreLoginFieldsValid()
        {
            if (!string.IsNullOrEmpty(emailLoginTextBox.Text) && passwordLoginTextBox.Password != null)
            {
                if (passwordLoginTextBox.Password.Trim().Length > 3)
                {
                    if (passwordLoginTextBox.Password.Length >= 50)
                    {
                        GlobalViewModel.ShowToast(AppResources.Error, AppResources.PasswordTooLong);
                        return false;
                    }
                    return true;
                }
                GlobalViewModel.ShowToast(AppResources.Error, AppResources.PasswordTooShort);
                return false;
            }
            GlobalViewModel.ShowToast(AppResources.Error, AppResources.EnterPasswordAndEmail);
            return false;
        }

        /// <summary>
        /// Validates registration fields
        /// </summary>
        private bool AreRegisterFieldsValid()
        {
            if (!string.IsNullOrEmpty(emailRegisterTextBox.Text) &&
                passwordRegisterTextBox.Password != null &&
                !string.IsNullOrEmpty(repeatEmailRegisterTextBox.Text))
            {
                if (passwordRegisterTextBox.Password.Trim().Length > 3)
                {
                    if (emailRegisterTextBox.Text == repeatEmailRegisterTextBox.Text)
                    {
                        if (passwordRegisterTextBox.Password.Length >= 50)
                        {
                            GlobalViewModel.ShowToast(AppResources.Error, AppResources.PasswordTooLong);
                            return false;
                        }
                        return true;
                    }
                    GlobalViewModel.ShowToast(AppResources.Error, AppResources.EmailsDontMatch);
                    return false;
                }
                GlobalViewModel.ShowToast(AppResources.Error, AppResources.PasswordTooShort);
                return false;
            }
            GlobalViewModel.ShowToast(AppResources.Error, AppResources.EnterPasswordAndEmail);
            return false;
        }

        #endregion

        #region callback methods

        /// <summary>
        /// Callback method for registering new user, redirects to books page.
        /// </summary>
        /// <param name="restResponse">The responce from the restSharp request</param>
        /// <param name="email">Users email</param>
        /// <param name="password">Users password</param>
        private void RegisterCallback(RestResponse restResponse, string email, string password)
        {
            if (restResponse.ResponseStatus == ResponseStatus.Completed)
            {
                IsRegisterInProgress(false);
                var response = restResponse.Content;
                // If user is validated create user object with books
                if (_userViewModel.ValidateLogin(response))
                {
                    _userViewModel.CreateCurrentUser(response, email, password);

                    GlobalViewModel.SetAppSetting("loggedIn", true);

                    // Supplies (fromLogin = "true") parameter to disable back button when user navigates from
                    // login page or signup page to books page.
                    NavigationService.Navigate(new Uri("/View/Books.xaml?fromLogin=true", UriKind.Relative));
                }
            }
            else
            {
                GlobalViewModel.ShowToast(AppResources.Error, AppResources.ErrorRegistering);
            }
        }

        /// <summary>
        /// Callback method for logging in, redirects to books page.
        /// </summary>
        /// <param name="restResponse">The responce from the restSharp request</param>
        /// <param name="email">Users email</param>
        /// <param name="password">Users password</param>
        private void LoginCallback(RestResponse restResponse, string email, string password)
        {
            if (restResponse.ResponseStatus == ResponseStatus.Completed && !string.IsNullOrEmpty(restResponse.Content))
            {
                var response = JsonSerializer.DeserializeFromString<Dictionary<string, string>>(restResponse.Content);

                // If user is validated create user object with books
                if (UserViewModel.ValidateLogin(response))
                {
                    _userViewModel.CreateCurrentUser(response, email, password);

                    // When user has been created, redirect to books page.
                    GlobalViewModel.SetAppSetting("loggedIn", true);

                    // Supplies (fromLogin = "true") parameter to disable back button when user navigates from
                    // login page to books page.
                    NavigationService.Navigate(new Uri("/View/Books.xaml?fromLogin=true", UriKind.Relative));
                }
                else
                {
                    IsLoggingInProgress(false);
                }
            }
            else
            {
                IsLoggingInProgress(false);
                GlobalViewModel.ShowToast(AppResources.Error, AppResources.ErrorLoggingIn);
            }
        }

        /// <summary>
        /// Callback method for forgot password
        /// </summary>
        /// <param name="restResponse">The responce from the restSharp request</param>
        /// <param name="email">Users email</param>
        private void ForgotPasswordCallback(RestResponse restResponse, string email)
        {
            IsForgotPasswordInProgress(false);
            if (restResponse.ResponseStatus == ResponseStatus.Completed)
            {
                switch (restResponse.Content)
                {
                    case "0":
                        GlobalViewModel.ShowToast(AppResources.Error, AppResources.EmailNotFound);
                        break;
                    case "":
                        GlobalViewModel.ShowToast(AppResources.Success, AppResources.EmailSent + email);
                        loginPivot.SelectedItem = loginPivotItem;
                        break;
                    default:
                        GlobalViewModel.ShowToast(AppResources.Error, AppResources.ErrorSendingPassword);
                        break;
                }
            }
            else
            {
                GlobalViewModel.ShowToast(AppResources.Error, AppResources.ErrorSendingPassword);
            }
        }

        #endregion

        #region eventHandlers

        private void SendPasswordButtonClick(object sender, RoutedEventArgs e)
        {
            // Check network availability
            if (NetworkInterface.GetIsNetworkAvailable())
            {
                var email = emailForgotTextBox.Text.ToLower();
                if (email.Length > 0)
                {
                    if (GlobalViewModel.ValidateEmail(email))
                    {
                        sendPasswordButton.Focus();
                        IsForgotPasswordInProgress(true);
                        _userViewModel.SendUserPasswordWebRequest(email.Trim(), ForgotPasswordCallback);
                    }
                    else
                    {
                        GlobalViewModel.ShowToast(AppResources.Error, AppResources.WrongEmail);
                    }
                }
                else
                {
                    GlobalViewModel.ShowToast(AppResources.Error, AppResources.EnterEmail);
                }
            }
            else
            {
                GlobalViewModel.ShowToast(AppResources.Error, AppResources.InternetProblem);
            }
        }

        private void LoginButtonClick(object sender, EventArgs e)
        {
            if (AreLoginFieldsValid())
            {
                loginButton.Focus(); // Removes keyboard
                var email = emailLoginTextBox.Text.ToLower();
                var password = passwordLoginTextBox.Password.ToLower();

                // Check if email is valid
                if (GlobalViewModel.ValidateEmail(email))
                {
                    // Check if user exists locally to avoid going to the internet. If user exists, redirect to books page.
                    if (UserViewModel.CheckIfLocalUserExists(email, password))
                    {
                        GlobalViewModel.SetAppSetting("loggedIn", true);
                        // Supplies (fromLogin = "true") parameter to disable back button when user navigates from
                        // login page to books page.
                        NavigationService.Navigate(new Uri("/View/Books.xaml?fromLogin=true", UriKind.Relative));
                        return;
                    }

                    // Check network availability and create new user on the phone.
                    if (NetworkInterface.GetIsNetworkAvailable())
                    {
                        IsLoggingInProgress(true);
                        _userViewModel.GetUserLoginWebRequest(email, password, LoginCallback);
                            // Web request that checks if user exists.
                    }
                    else
                    {
                        GlobalViewModel.ShowToast(AppResources.Error, AppResources.InternetProblem);
                    }
                }
                else
                {
                    GlobalViewModel.ShowToast(AppResources.Error, AppResources.WrongEmail);
                }
            }
        }

        private void RegisterButtonClick(object sender, RoutedEventArgs e)
        {
            // Check network availability
            if (NetworkInterface.GetIsNetworkAvailable())
            {
                if (AreRegisterFieldsValid())
                {
                    registerButton.Focus();
                    var email = emailRegisterTextBox.Text.ToLower();
                    var password = passwordRegisterTextBox.Password.ToLower();

                    if (GlobalViewModel.ValidateEmail(email))
                    {
                        IsRegisterInProgress(true);
                        _userViewModel.SignUpWebRequest(email.Trim(), password, RegisterCallback);
                    }
                    else
                    {
                        GlobalViewModel.ShowToast(AppResources.Error, AppResources.WrongEmail);
                    }
                }
            }
            else
            {
                GlobalViewModel.ShowToast(AppResources.Error, AppResources.InternetProblem);
            }
        }

        /// <summary>
        /// Clicks "sign up" when enter is pressed in password box of register page.
        /// </summary>
        private void PasswordRegisterTextBoxKeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                RegisterButtonClick(sender, e);
            }
        }

        /// <summary>
        /// Logs user in when enter is pressed in password box.
        /// </summary>
        private void PasswordLoginTextBoxKeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                LoginButtonClick(sender, e);
            }
        }

        /// <summary>
        /// Clicks "send password" when enter is pressed in forgot password box.
        /// </summary>
        private void EmailForgotTextBoxKeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                SendPasswordButtonClick(sender, e);
            }
        }

        // Hides log in controls and shows forgot password controls
        private void ForgotPasswordButtonClick(object sender, RoutedEventArgs e)
        {
            loginPivot.SelectedItem = forgotPasswordPivotItem;
        }

        #endregion
    }
}